<?php


namespace Gaoop\Bundle\ApiBundle\EventListener;


use Doctrine\Common\Annotations\AnnotationReader;
use Gaoop\Bundle\ApiBundle\Annotation\ApiAuthority;
use Gaoop\Bundle\ApiBundle\Traits\HelperTrait;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class ApiAuthorityListener {
    use HelperTrait;

    private $annotationReader;

    public function __construct () {
        $this->annotationReader = new AnnotationReader();
    }

    public function onKernelController (ControllerEvent $event): void {
        if (!$event->isMasterRequest()) {
            return;
        }

        $controllers = $event->getController();
        if (!is_array($controllers)) {
            return;
        }

        [$controller, $method] = $controllers;

        $this->handleApiAuthority($controller, $method);
    }

    /**
     * 权限接口校验
     * @param $controller
     * @param string $method
     * @param ParameterBagInterface $parameterBag
     * @throws \ReflectionException
     */
    private function handleApiAuthority ($controller, string $method, ParameterBagInterface $parameterBag): void {
        $ref = new \ReflectionClass($controller);
        $method = $ref->getMethod($method);
        $annotation = $this->annotationReader->getMethodAnnotation($method, ApiAuthority::class);
        if ($annotation instanceof ApiAuthority) {
            $admin_user = $this->getAdminUser();
            if (!is_object($admin_user)) {
                throw new AccessDeniedException('User not logged in.');
            }
            $admin_modules = $parameterBag->get('authority_admin_modules');
            if (!in_array($annotation->need, $admin_modules)) {
                throw new AccessDeniedException('Access Denied.');
            }
        }
    }
}